#include <windows.h>
#include "GameTime.h"

// -------------------------------- //

GameTime::GameTime()
	: m_secondsPerCount(0.0)
	, m_elapsedTime(-1.0)
	, m_startTime(0)
	, m_pausedTime(0)
	, m_previousTime(0)
	, m_currentTime(0)
	, m_isStopped( false )
{
	__int64 countsPerSec;
	QueryPerformanceFrequency( ( LARGE_INTEGER* )&countsPerSec );
	m_secondsPerCount = 1.0 / ( double )countsPerSec;
}

// -------------------------------- //

float GameTime::GetTotalTime() const
{
	if ( m_isStopped )
	{
		return ( float )( ( ( m_stopTime - m_pausedTime ) - m_startTime ) * m_secondsPerCount );
	}

	return ( float )( ( ( m_currentTime - m_pausedTime ) - m_startTime ) * m_secondsPerCount );
}

// -------------------------------- //

float GameTime::GetElapsedTime() const
{
	return ( float )m_elapsedTime;
}

// -------------------------------- //

void GameTime::Reset()
{
	__int64 currentTime;
	QueryPerformanceCounter( ( LARGE_INTEGER* )&currentTime );

	m_startTime		= currentTime;
	m_previousTime	= currentTime;
	m_stopTime		= 0;
	m_isStopped		= false;
}

// -------------------------------- //

void GameTime::Start()
{
	__int64 startTime;
	QueryPerformanceCounter( ( LARGE_INTEGER* )&startTime );

	if ( m_isStopped )
	{
		m_pausedTime	+= ( startTime - m_stopTime );	
		m_previousTime	= startTime;
		m_stopTime		= 0;
		m_isStopped		= false;
	}
}

// -------------------------------- //

void GameTime::Pause()
{
	if ( !m_isStopped )
	{
		__int64 currentTime;
		QueryPerformanceCounter( ( LARGE_INTEGER* )&currentTime );

		m_stopTime	 = currentTime;
		m_isStopped  = true;
	}
}

// -------------------------------- //

void GameTime::Tick()
{
	if ( m_isStopped )
	{
		m_elapsedTime = 0.0;
		return;
	}

	__int64 currentTime;
	QueryPerformanceCounter( ( LARGE_INTEGER* )&currentTime );
	m_currentTime = currentTime;

	// Time difference between this frame and the previous.
	m_elapsedTime = ( m_currentTime - m_previousTime ) * m_secondsPerCount;

	// Prepare for next frame.
	m_previousTime = m_currentTime;

	// Force nonnegative.
	if ( m_elapsedTime < 0.0 )
	{
		m_elapsedTime = 0.0;
	}
}
